// MainWnd.cpp: implementation of the CMainWnd class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MainWnd.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMainWnd::CMainWnd():
	m_hWnd(NULL),
	m_fAngle(0.0f),
	m_hRC(NULL)
{
	m_sel = 0;
}

CMainWnd::~CMainWnd()
{
}

//
// InitScene()
// Called when the OpenGL RC has been created. Sets the initial state for
// the OpenGL scene.
//
void CMainWnd::InitScene()
{
	glClearColor(0.000f, 0.000f, 0.000f, 1.0f); //Background color
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);

	m_trf[0] = 0.0f;
	m_trf[1] = 0.0f;
	m_trf[2] = -5.0f;

	for(int i=0; i<10; i++)
	{
		char file[64];
		if(i < -1)
		{
			sprintf(file, "test%d.jpg", i);
			load(file, m_tid[i], CXIMAGE_FORMAT_JPG);
		}
		else
		{
			sprintf(file, "fruit%d.png", i);
			load(file, m_tid[i], CXIMAGE_FORMAT_PNG);
		}
	}

	load("bk.png", m_bkid, CXIMAGE_FORMAT_PNG);
}

bool CMainWnd::load(const char* szFile, GLuint& tid, DWORD dwFormat)
{
	CxImage image;
	if(image.Load(szFile, dwFormat))
	{
		BYTE* pPixes = NULL;
		long lSize = 0;

		if(!image.AlphaIsValid())
		{
			image.Encode(pPixes, lSize, CXIMAGE_FORMAT_BMP);
			if(pPixes)
			{
				glGenTextures(1, &tid);
				
				GLsizei w = image.GetWidth();
				GLsizei h = image.GetHeight();
				
				glBindTexture( GL_TEXTURE_2D, tid );
				glTexImage2D( GL_TEXTURE_2D, 0, 3, w, h, 0,
					GL_RGB, GL_UNSIGNED_BYTE, pPixes);
				
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

				image.FreeMemory(pPixes);
				return true;
			}

		}
		else
		{
			image.Encode2RGBA(pPixes, lSize);
			if(pPixes)
			{
				glGenTextures(1, &tid);
				
				GLsizei w = image.GetWidth();
				GLsizei h = image.GetHeight();
				
				glBindTexture( GL_TEXTURE_2D, tid );
				glTexImage2D( GL_TEXTURE_2D, 0, 4, w, h, 0,
					GL_RGBA, GL_UNSIGNED_BYTE, pPixes);
				
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

				image.FreeMemory(pPixes);
				return true;
			}
		}
	}
	return false;
}

//
// KillScene()
// Called when the OpenGL RC is about to be destroyed. 
//
void CMainWnd::KillScene()
{
	// TODO: Use KillScene to free resources.
}

void CMainWnd::GL3DWall(BOOL bSelect)
{
	glInitNames();
	glPushName(0);

	//glPushMatrix();
	
	GLfloat w, h, s;
	GLfloat x1, y1, x2, y2, z;
	w = h = 2.0f;
	s = 0.6f;

	x1 = -1.0f; 
	y1 = -1.0f;
	x2 = 1.0f;
	y2 = 1.0f;
	z = 0.0f;

	GLfloat sx1, sy1, sx2, sy2;

	GLuint name = 1;

	glColor3f(1.0f, 1.0f, 1.0f); 
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
	for(int j=0; j<3; j++)
	{
		for(int i=0; i<10; i++)
		{
			glBindTexture(GL_TEXTURE_2D, m_tid[i]);
			glLoadName(name);
			glBegin(GL_QUADS);
				glTexCoord2f(0.0f, 0.0f); glVertex3f(x1, y1, z);
				glTexCoord2f(1.0f, 0.0f); glVertex3f(x2, y1, z);
				glTexCoord2f(1.0f, 1.0f); glVertex3f(x2, y2, z);
				glTexCoord2f(0.0f, 1.0f); glVertex3f(x1, y2, z);
			glEnd();

			if(name == m_sel)
			{
				sx1 = x1;
				sy1 = y1;
				sx2 = x2;
				sy2 = y2;
			}

			name++;
			
			x1 = x2 + s;
			x2 = x1 + w;
		}
		
		x1 = -1.0f; 
		y2 = y1 - s;
		x2 = 1.0f;
		y1 = y2 - h;
	}

	glPopName();
	//glPopMatrix();

	if(!bSelect)
	{
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		for(int i=0; i<10; i++)
		{
			glBindTexture(GL_TEXTURE_2D, m_tid[i]);
			glBegin(GL_QUADS);
				glColor3f(0.0f, 0.0f, 0.0f); 
				glTexCoord2f(0.0f, 1.0f); glVertex3f(x1, y1, z);
				glColor3f(0.0f, 0.0f, 0.0f); 
				glTexCoord2f(1.0f, 1.0f); glVertex3f(x2, y1, z);
				glColor3f(0.2f, 0.2f, 0.2f); 
				glTexCoord2f(1.0f, 0.0f); glVertex3f(x2, y2, z);
				glColor3f(0.2f, 0.2f, 0.2f); 
				glTexCoord2f(0.0f, 0.0f); glVertex3f(x1, y2, z);
			glEnd();

			x1 = x2 + s;
			x2 = x1 + w;
		}

		if(m_sel > 0)
		{
			GLfloat f = 0.2f;
			x1 = sx1 - f; 
			y1 = sy1 - f;
			x2 = sx2 + f;
			y2 = sy2 + f;
			z = -0.01f;

			glColor3f(0.0f, 0.0f, 0.0f); 
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
			glBindTexture(GL_TEXTURE_2D, m_bkid);
			glBegin(GL_QUADS);
				glTexCoord2f(0.0f, 1.0f); glVertex3f(x1, y1, z);
				glTexCoord2f(1.0f, 1.0f); glVertex3f(x2, y1, z);
				glTexCoord2f(1.0f, 0.0f); glVertex3f(x2, y2, z);
				glTexCoord2f(0.0f, 0.0f); glVertex3f(x1, y2, z);
			glEnd();

			f = 0.0f;
			x1 = sx1 - f; 
			y1 = sy1 - f;
			x2 = sx2 + f;
			y2 = sy2 + f;
			z = 0.0f;

			/*
			glColor3f(1.0f, 1.0f, 1.0f); 
			glLineWidth(5.0f);
			glBegin(GL_LINE_LOOP);
				glVertex3f(x1, y1, z);
				glVertex3f(x2, y1, z);
				glVertex3f(x2, y2, z);
				glVertex3f(x1, y2, z);
			glEnd();
			*/

			glColor3f(0.3f, 0.3f, 0.3f); 
			glLineWidth(2.0f);
			glBegin(GL_LINE_LOOP);
				glVertex3f(x1, y1, z);
				glVertex3f(x2, y1, z);
				glVertex3f(x2, y2, z);
				glVertex3f(x1, y2, z);
			glEnd();

		}
	}

}

//
// DrawScene()
// Called each time the OpenGL scene has to be drawn.
//
void CMainWnd::DrawScene()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear buffers

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	// Position and rotate the camera
	glTranslatef(m_trf[0], m_trf[1], m_trf[2]);

	GL3DWall();

	glFlush();

	glPopMatrix();
}

void CMainWnd::Pick(int x, int y)
{
	const int BUFFER_LENGTH = 64;

	GLuint pSelectBuffer[BUFFER_LENGTH];

	GLint hits = 0;

	GLint viewport[4] = {0, 0, 0, 0};
	glGetIntegerv(GL_VIEWPORT, viewport);

	glSelectBuffer(BUFFER_LENGTH, pSelectBuffer);
	glRenderMode(GL_SELECT);
	
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();

	glLoadIdentity();

	gluPickMatrix(x, viewport[3]-y, 1, 1, viewport);

	RECT rv;
	GetClientRect(m_hWnd, &rv);
	GLfloat fAspect = (GLfloat)(rv.right-rv.left) / (GLfloat)(rv.bottom-rv.top);

	GLfloat fFovy  = 30.0f; // Field-of-view
	GLfloat fZNear = 1.0f;  // Near clipping plane
	GLfloat fZFar = 1000.0f;  // Far clipping plane

	gluPerspective(fFovy, fAspect, fZNear, fZFar);

	DrawScene();

	hits = glRenderMode(GL_RENDER);

	if(hits > 0)
	{
		m_sel = pSelectBuffer[3];
		char s[12];
		sprintf(s, "\n%d", pSelectBuffer[3]);
		OutputDebugString(s);
		MessageBeep(-1);
	}

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	

}
